package com.ray.test.proxy.asm;

import org.objectweb.asm.ClassAdapter;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;

import java.lang.reflect.Method;

/**
 * @author bo shen
 * @Description: asm aop class
 * @Class: AsmAopClassAdapter
 * @Package com.ray.test.proxy.asm
 * @date 2019/12/20 11:11
 * @company <p>杭州传化陆鲸科技有限公司</p>
 * @updateRecord time(修改时间)  author(修改人)   desc(修改内容)
 */
public class AsmAopClassAdapter  extends ClassAdapter {
    private String enhancedSuperName,enhancedName;

    private Method method;


    public AsmAopClassAdapter(ClassVisitor cv, Method methodName) {
        super(cv);
        method = methodName;

    }

    // 重写 visitMethod，访问到 "method" 方法时，
    // 给出自定义 MethodVisitor，实际改写方法内容
    public MethodVisitor visitMethod(final int access, final String name,
                                     final String desc, final String signature, final String[] exceptions) {
        MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);
        MethodVisitor wrappedMv = mv;
        if (mv != null) {
            if (name.equals(method.getName())) {
                wrappedMv = new AsmAopMethodAdapter(mv,method);
            } else if (name.equals("<init>")) {
                wrappedMv = new ChangeToChildConstructorMethodAdapter(mv,enhancedSuperName);
            }
        }
        return wrappedMv;
    }

    public void visit(final int version, final int access, final String name,
                      final String signature, final String superName,
                      final String[] interfaces) {
        enhancedName = name.replace("/", "$")+"$EnhancedByASM";  // 改变类命名
        enhancedSuperName = name; // 改变父类
        super.visit(version, access, enhancedName, signature,
                enhancedSuperName, interfaces);
    }

    public String getEnhancedName() {
        return enhancedName;
    }
}
